﻿using System;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Homework1
{
    public partial class MainWindow : Form
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void MainWindow_Load(object sender, EventArgs e)
        {
            var settingsWindow = new SettingsWindow();
            if (settingsWindow.ShowDialog() == DialogResult.OK)
            {
                DB.CreateDatabase(DB.DatabaseName);
                DB.CreateTables();
                DB.SyncSchemaToDatabase();
            }
            else
            {
                Close();
            }
        }

        private void SearchButton_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrWhiteSpace(SearchTextBox.Text))
            {
                MessageBox.Show("Please input a search term.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }

            Cursor = Cursors.WaitCursor;

            WebpagesDataGridView.DataSource = null;
            LinksDataGridView.DataSource = null;

            // Run the search
            var task = Task.Factory.StartNew(() =>
                                             {
                                                 if (ClearDbCheckBox.Checked)
                                                 {
                                                     DB.ClearData(); // Clear out existing DB data
                                                 }
                                                 GoogleQuery.GoogleSearch(SearchTextBox.Text.Replace(' ', '+'),
                                                                          Int32.Parse(MaxResultsTextBox.Text),
                                                                          Int32.Parse(MaxDepthTextBox.Text),
                                                                          Int32.Parse(MaxTraverseTextBox.Text));
                                             });
            
            // After the search task is done, results will be synced to the database and also
            // displayed in grid views
            task.ContinueWith(t =>
                              {
                                  if (DB.SyncSchemaToDatabase())
                                  {
                                      Invoke(new MethodInvoker(() =>
                                                               {
                                                                   WebpagesDataGridView.DataSource = DB.Schema.Webpages;
                                                                   LinksDataGridView.DataSource = DB.Schema.Links;
                                                               }));
                                  }
                                  Invoke(new MethodInvoker(() => { Cursor = Cursors.Default; }));
                              });
        }

        // Finds all documents which are linked through paths of length <= 2, contain only local links, 
        // and have 'faculty' in their title.
        private void Query1Button_Click(object sender, EventArgs e)
        {
            var query1 = string.Format(@"SELECT l.label, l.Url from `{0}`.`webpages` w
                                         JOIN `{0}`.`links` l ON w.Guid = l.FromGuid
                                         WHERE w.BaseUrl = ""cs.mst.edu"" AND l.label LIKE ""%faculty%"" AND l.IsInternal = true;", DB.DatabaseName);

            Query1Button.Enabled = false;
            var task = Task.Factory.StartNew(() =>
                                             {
                                                 var results = DB.GetDataTableFromQuery(query1);
                                                 if (results != null)
                                                 {
                                                     Invoke(new MethodInvoker(() => { Query1DataGridView.DataSource = results; }));
                                                 }
                                             });
            task.ContinueWith(t =>
                              {
                                  Invoke(new MethodInvoker(() => { Query1Button.Enabled = true; }));
                              });
        }

        // Obtains the link base and link label for all pages with length >100 and which have the text 'xml'
        private void Query2Button_Click(object sender, EventArgs e)
        {
            var query2 = string.Format(@"SELECT l.BaseUrl, l.Label
                                         FROM `{0}`.`webpages` w
                                         JOIN `{0}`.`links` l ON w.Guid = l.FromGuid
                                         WHERE CHAR_LENGTH(w.Text) > 100 AND w.Text LIKE ""%XML%"";", DB.DatabaseName);

            Query2Button.Enabled = false;
            var task = Task.Factory.StartNew(() =>
                                             {
                                                 var results = DB.GetDataTableFromQuery(query2);
                                                 if (results != null)
                                                 {
                                                     Invoke(new MethodInvoker(() => { Query2DataGridView.DataSource = results; }));
                                                 }
                                             });
            task.ContinueWith(t =>
                              {
                                  Invoke(new MethodInvoker(() => { Query2Button.Enabled = true; }));
                              });
        }

        // From the local links of the results, obtains the URLs of....?
        private void Query3Button_Click(object sender, EventArgs e)
        {
            var query3 = string.Format(@"SELECT w2.url 
                                         FROM `{0}`.`webpages` w2
                                         WHERE w2.Guid IN
                                               (SELECT l3.FromGuid 
                                                FROM  `{0}`.`links` l3
                                                WHERE l3.IsInternal = false and l3.ToGuid IN
                                                      (select w1.Guid 
                                                       FROM `{0}`.`webpages` w1
                                                       WHERE w1.BaseUrl = '{1}'))
                                         or w2.Guid IN 
                                            (SELECT l1.FromGuid 
                                            FROM `{0}`.`links` l1
                                            WHERE l1.IsInternal = true and l1.ToGuid IN 
                                                (SELECT l2.FromGuid 
                                                 FROM `{0}`.`links` l2
                                                 WHERE l2.IsInternal = false and l2.ToGUid IN 
                                                        (SELECT w1.Guid 
                                                         FROM `{0}`.`webpages` w1
                                                         WHERE w1.BaseUrl = '{1}')))", DB.DatabaseName, SiteToFindTextBox.Text);

            Query3Button.Enabled = false;
            var task = Task.Factory.StartNew(() =>
                                             {
                                                 var results = DB.GetDataTableFromQuery(query3);
                                                 if (results != null)
                                                 {
                                                     Invoke(new MethodInvoker(() => { Query3DataGridView.DataSource = results; }));
                                                 }
                                             });
            task.ContinueWith(t =>
                              {
                                  Invoke(new MethodInvoker(() => { Query3Button.Enabled = true; }));
                              });
        }
    }
}
